from types import GeneratorType

from wheels.pi.coro._CoroFrame import CoroFrame
from wheels.pi.coro._SystemCall import SystemCall



class TaskProcessor(object):

    def __init__(self, kernel):
        self._kernel = kernel


    def run_task(self, td, val=None, err=None):
        while True:
            try:
                if err:
                    ret = td.coro_stack.coro.throw(*err)
                else:
                    ret = td.coro_stack.coro.send(val)
                if isinstance(ret, SystemCall):
                    self._kernel._system_call(ret, td.tid)
                    break
                if isinstance(ret, GeneratorType):
                    td.coro_stack = _CoroFrame(ret, td.coro_stack)
                    val, err = None, None
                    continue
                if td.coro_stack.return_coro:
                    td.coro_stack = td.coro_stack.return_coro
                    val, err = ret, None
                else:
                    self._kernel._schedule_task(td.tid)
                    break
            except StopIteration:
                if td.coro_stack.return_coro:
                    td.coro_stack = td.coro_stack.return_coro
                    val, err = None, None
                else:
                    self._kernel._terminate_task(td.tid, status=0)
                    break
